const _crypto = require("crypto-js"); // 注意查看文档(巨坑)
const Base64 = require('./alioss/base64.js');
const Crypto = require('./alioss/crypto.js');
const rp = require('request-promise');

const aliKey = {
  accessKeyID: 'LTAI5tCGjgBhzpeSkjPJ7v43',
  accessKeySecret: 'DvI1YMb0si6IDBE2NKY8GSBCVC58W2',
  host: 'https://qiqi-tool.oss-cn-shanghai.aliyuncs.com',
  timeout: 87600,
};

async function productDivideApi(ctx, db) {
  let param = ctx._req.event.param;
  let result = await productDivide(param.ImageURL, param.ReturnForm);
  return result;
}

async function hdProductDivideApi(ctx, db) {
  let param = ctx._req.event.param;
  let result = await hdProductDivide(param.ImageURL);
  return result;
}

function getOssUploadKey(ctx, db) {
  let param = ctx._req.event.param;
  let aliyunFileKey = param.aliyunFileKey;
  const policyBase64 = Base64.encode(JSON.stringify({
    "expiration": new Date(new Date().getTime() + aliKey.timeout).toISOString(),
    "conditions": [
      ["content-length-range", 0, 1024 * 1024 * 100] //100m
    ]
  }));
  let bytes = _crypto.HmacSHA1(policyBase64, aliKey.accessKeySecret);
  const signature = _crypto.enc.Base64.stringify(bytes);
  return {
    'aliyunServerURL': aliKey.host,
    'key': aliyunFileKey,
    'OSSAccessKeyId': aliKey.accessKeyID,
    'policy': policyBase64,
    'Signature': signature,
    'success_action_status': '200',
  };
}

async function hdProductDivide(ImageURL) {
  let param = {
    Action: 'SegmentHDCommonImage',
    ImageUrl: ImageURL,
    Version: '2019-12-30'
  };
  return request(param, 'https://imageseg.cn-shanghai.aliyuncs.com/?')
}

async function productDivide(ImageURL, ReturnForm) {
  let param = {
    Action: 'SegmentCommodity',
    ImageURL: ImageURL,
    Version: '2019-12-30'
  };
  if (ReturnForm != null) {
    param['ReturnForm'] = ReturnForm;
  }
  return request(param, 'https://imageseg.cn-shanghai.aliyuncs.com/?')
}

async function request(param, platformUrl) {
  let basequery = {
    AccessKeyId: aliKey.accessKeyID,
    Format: "JSON",
    SignatureMethod: "HMAC-SHA1",
    SignatureNonce: uuid(),
    SignatureVersion: "1.0",
    Timestamp: new Date().toISOString().replace(/\..+/, '') + 'Z',
    RegionId: "cn-shanghai"
  };
  let query = {
    ...basequery,
    ...param
  };
  let _url = platformUrl + buildSignQueryString(query);
  let _signValue = getSignature(query, "GET");
  _url = _url + "&Signature=" + _signValue;
  console.log(_url);
  return rp.get(_url).then(res => JSON.parse(res));
}

function uuid() {
  var s = [];
  var hexDigits = "0123456789abcdef";
  for (var i = 0; i < 36; i++) {
    s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
  }
  s[14] = "4";
  s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
  s[8] = s[13] = s[18] = s[23] = "-";
  return s.join("");
}

/**
 * @param data json字符串字节流
 * @desc 用于生成签名拼接字符串QueryString。
 *      1.按ASCII码从小到大排序，空键/值和空字符串不参与组串
 *      2.统一使用UTF8进行编码签名，防止编码方式或特殊字符不兼容问题
 *      3.签名原始串中，字段名和字段值都采用原始值，即不进行URL Encode
 *      4.注意整形、浮点型数据参与签名方式（如：浮点数3.10体现为3.1、0.0体现为0）
 *      5.内嵌JSON或ARRAY解析拼接需转字符串且按紧凑方式，即内嵌各K/V或值之间不应有空格或换行符等等
 *      6.内部值中嵌套对象中空值或空字符串不做任何处理（即保留），空值统一使用null
 *      7.内部值中的嵌套对象键值属性保持原有顺序，不做特殊排序处理
 */
function buildSignQueryString(params) {
  var keys = Object.keys(params).sort()
  var queryString = "";
  keys.forEach((key, index) => {
    var val = params[key];
    if (key == undefined || key == null || key.length == 0 || val == undefined || val == null || val.length == 0) {
      return
    }
    if (queryString.length > 0) {
      queryString += "&"
    }
    queryString += key + "="
    switch (typeof (val)) {
      case "object":
        queryString += JSON.stringify(val, (k, v) => typeof v === 'undefined' ? null : v);
        break;
      default:
        queryString += val;
        break;
    }
  })
  return queryString;
}

function getSignature(params, method) {
  let _ret = "";
  console.log("Params", params);
  let sign = Object.entries(params)
    .sort(function (k1, k2) {
      return k1[0].localeCompare(k2[0]);
    })
    .reduce(function (total, curV, curI, arr) {
      return curI < (arr.length - 1) ? `${total}${curV[0]}=${encodeURIComponent(curV[1])}&` : `${total}${curV[0]}=${encodeURIComponent(curV[1])}`
    }, "");
  sign = method + "&%2F&" + encodeURIComponent(sign);
  let _signWords = _crypto.enc.Utf8.parse(sign);
  let _signUtf8 = _crypto.enc.Utf8.stringify(_signWords);
  console.log(_signUtf8);
  let _secret = aliKey.accessKeySecret + "&";
  console.log(_secret);
  let _hmacsha1 = _crypto.HmacSHA1(sign, _secret);
  console.log(_hmacsha1.toString());
  _ret = encodeURIComponent(_crypto.enc.Base64.stringify(_hmacsha1));
  console.log(_ret);
  return _ret;
}

module.exports = {
  productDivideApi,
  hdProductDivideApi,
  getOssUploadKey
}